import 'dart:convert';
import 'dart:typed_data';

import 'package:inmotion_pro/custom_exception/lx_exception.dart';
import 'package:inmotion_pro/http/api_helper.dart';
import 'package:inmotion_pro/http/api_helper_tbox.dart';
import 'package:inmotion_pro/l10n/local.dart';
import 'package:inmotion_pro/pages/mixin/cache_mixin.dart';
import 'package:inmotion_pro/pages/mixin/controller_mixin.dart';
import 'package:inmotion_pro/pages/mixin/protocol_mixin.dart';
import 'package:inmotion_pro/pages/mixin/realtime_info_mixin.dart';
import 'package:inmotion_pro/pages/mixin/vehicle_type_mixin.dart';
import 'package:inmotion_pro/pages/models/vehicle_model.dart';
import 'package:inmotion_pro/pages/protocol_business/base/base_business.dart';
import 'package:inmotion_pro/pages/protocol_business/lorin/lorin_business.dart';
import 'package:inmotion_pro/service/global_service.dart';
import 'package:ble_helper_plugin/library.dart';
import 'package:bluetooth_protocols_parser_plugin/library.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:inmotion_pro/service/realtime_data_server/realtime_data_polling_timer_helper.dart';

import 'cache_config_service.dart';

// 车辆协议枚举
enum VechileProtocolEnum {
  lorin,
  huari,
}

// 车辆连接服务
class VechileConnectionService extends GetxService
    with
        CacheMixin,
        VehicleTypeMixin,
        ProtocolMixin,
        RealtimeInfoMixin,
        ControllerMixin {
  // 车辆连接服务
  static VechileConnectionService get to => Get.find().._setUuidAdapters();

  // 蓝牙连接助手
  late BluetoothConnectHelper? bluetoothConnectHelper;

  // 蓝牙状态监听器
  Rx<CustomBluetoothConnectState> bluetoothConnectState =
      CustomBluetoothConnectState.disconnected.obs;

  // 根据蓝牙设备类型，初始化不同的业务协议
  BaseBusiness? business;

  // 蓝牙协议
  // 1.Lorin 根据车辆名称，确定蓝牙协议类型
  // 2.Huari 根据蓝牙广播数据的sn，确定蓝牙协议类型
  Protocol? protocol;

  // 蓝牙协议类型
  late Rx<VechileProtocolEnum?> protocolType = Rx<VechileProtocolEnum?>(null);

  // 当前连接车辆
  VehicleModel? get connectedDevice {
    String? connectedBleName = bluetoothConnectHelper?.connectedDevice?.advName;
    if (connectedBleName != null) {
      try {
        return GlobalService.to.cacheVehicleList.firstWhere(
          (element) => element.bleName == connectedBleName,
        );
      } catch (e) {
        return null;
      }
    } else {
      return null;
    }
  }

  // 获取当前车辆的连接方式
  MessageSendMethod get connectedMethod =>
      protocol?.messageSendMethod ?? MessageSendMethod.bluetooth;

  // 获取当前车辆的最大mtu
  Future<int?> get mtu async {
    return await VechileConnectionService
        .to.bluetoothConnectHelper?.connectedDevice?.mtu.first;
  }

  // 默认支持的蓝牙协议
  final List<VechileProtocolEnum> _defaultSupportedProtocols = [
    VechileProtocolEnum.lorin,
    VechileProtocolEnum.huari,
  ];

  // 支持的蓝牙协议适配器
  List<BluetoothUuidAdapterBase> get _supportedUuidAdapters =>
      _getUuidAdapters(_defaultSupportedProtocols);

  // 设置蓝牙协议适配器
  _setUuidAdapters() {
    // 初始化蓝牙助手
    bluetoothConnectHelper = BluetoothConnectHelper(_supportedUuidAdapters);
    // 蓝牙连接助手状态监听
    bluetoothConnectHelper?.bluetoothConnectState.listen((state) async {
      bluetoothConnectState.value = state;
      switch (state) {
        case CustomBluetoothConnectState.connected:
          break;
        case CustomBluetoothConnectState.disconnected:
          // 如果断开连接，则清除当前业务和协议
          business = null;
          protocol = null;
          protocolType.value = null;
          // 断开安全连接
          await CacheConfigService.to.setSecureConnection(false);
          break;
        default:
          break;
      }
    });
  }

  // 获取支持蓝牙连接的UUID适配器
  List<BluetoothUuidAdapterBase> _getUuidAdapters(
      List<VechileProtocolEnum> protocols) {
    List<BluetoothUuidAdapterBase> supportAdapters = [];
    for (var protocol in protocols) {
      if (protocol == VechileProtocolEnum.lorin) {
        // 如果支持乐行协议
        supportAdapters.add(LorinBluetoothUuidAdapter());
      } else if (protocol == VechileProtocolEnum.huari) {
        // 如果支持华锐协议
        supportAdapters.add(HuariBluetoothUuidAdapter());
      }
    }
    return supportAdapters;
  }

  // 初始化蓝牙协议
  Future<bool> initializeVehicleProtocol({
    CustomScanResult? scanResult,
    VehicleModel? vehicleModel,
  }) async {
    if (protocol != null) {
      // 已经初始化过协议，直接返回成功
      return Future.value(true);
    }
    if (scanResult == null && vehicleModel == null) {
      throw LxException("initProtocol时scanResult 和 vehicleModel 不能同时为 null");
    }
    if (scanResult != null) {
      for (var service in await scanResult.device.discoverServices()) {
        for (var element in _supportedUuidAdapters) {
          if (element.writeServiceUuid == service.uuid.toString()) {
            protocolType.value = _getProtocolByUuidAdapter(element);
            if (protocolType.value != null) {
              switch (protocolType.value!) {
                case VechileProtocolEnum.lorin:
                  String bleName = scanResult.device.advName;
                  if (vehicleTypeMixinIsV12s(bleName: bleName) ||
                      vehicleTypeMixinIsV9(bleName: bleName)) {
                    protocol = V12sProtocol();
                  } else if (vehicleTypeMixinIsRsJet(bleName: bleName)) {
                    protocol = RsJetProtocol();
                  } else if (vehicleTypeMixinIsP6(bleName: bleName)) {
                    protocol = P6Protocol();
                  }
                  business = LorinBusiness();
                  break;
                default:
                  protocol = null;
                  business = null;
                  break;
              }
            }
          }
        }
      }
    } else if (vehicleModel != null) {
      // 暂不考虑Huari协议
      String bleName = vehicleModel.bleName;
      if (vehicleTypeMixinIsV12s(bleName: bleName) ||
          vehicleTypeMixinIsV9(bleName: bleName)) {
        protocol = V12sProtocol();
      } else if (vehicleTypeMixinIsRsJet(bleName: bleName)) {
        protocol = RsJetProtocol();
      } else if (vehicleTypeMixinIsP6(bleName: bleName)) {
        protocol = P6Protocol();
      } else {
        protocol = null;
      }
      business = protocol != null ? LorinBusiness() : null;
      protocolType.value = protocol != null ? VechileProtocolEnum.lorin : null;
    }
    debugPrint("协议类型: $protocolType - ${protocol?.runtimeType}");
    if (protocolType.value == null) {
      debugPrint("=== 未知的协议类型 ===");
      if (scanResult != null) {
        debugPrint("=== ${scanResult.device.advName} ===");
      } else if (vehicleModel != null) {
        debugPrint("=== ${vehicleModel.bleName} ===");
      }
      debugPrint("=== 未知的协议类型 ===");
      throw LxException(local.device_type_not_supported);
    }
    return protocol != null;
  }

  // 通过BluetoothUuidAdapterBase获取协议
  VechileProtocolEnum? _getProtocolByUuidAdapter(
      BluetoothUuidAdapterBase uuidAdapter) {
    if (uuidAdapter is LorinBluetoothUuidAdapter) {
      return VechileProtocolEnum.lorin;
    } else if (uuidAdapter is HuariBluetoothUuidAdapter) {
      return VechileProtocolEnum.huari;
    }
    return null;
  }

  // MARK: - 车辆云盒连接方式配置
  // 车辆连接方式变更 - 查询云盒状态与唤醒车辆时，会调用此方法，更新车辆连接方式
  /// [bluetoothConnectState] 蓝牙连接状态
  /// [himcStatus] 人机连接状态
  Future<void> updateVehicleConnectionMethod(bool himcStatus) {
    CustomBluetoothConnectState bluetoothConnectState =
        this.bluetoothConnectState.value;
    if (bluetoothConnectState == CustomBluetoothConnectState.connected &&
        himcStatus) {
      // 蓝牙和人机都连接成功，此时只保持蓝牙优先连接
      return _setVehicleConnetionMethod(MessageSendMethod.bluetooth);
    } else if (bluetoothConnectState == CustomBluetoothConnectState.connected &&
        !himcStatus) {
      // 仅蓝牙连接成功，设置为蓝牙连接
      return _setVehicleConnetionMethod(MessageSendMethod.bluetooth);
    } else if (bluetoothConnectState != CustomBluetoothConnectState.connected &&
        himcStatus) {
      // 仅云盒连接成功，设置为HTTP连接，此时需要手动启动轮询获取实时数据
      return _setVehicleConnetionMethod(MessageSendMethod.http);
    } else {
      debugPrint("⚠️ 蓝牙和云盒都未连接成功，无法设置车辆连接方式");
      // 都未连接成功，什么都不做
      return Future.value();
    }
  }

  // 设置车辆连接方式 支持【Bluetooth、HTTP、Bluetooth & HTTP 】
  Future<void> _setVehicleConnetionMethod(MessageSendMethod method) {
    debugPrint("✅✅✅ 当前车辆连接方式为: 【$method】");
    if (protocol == null) {
      return initializeVehicleProtocol(
              vehicleModel: GlobalService.to.currentVehicleModel.value)
          .then((initProtocolSuccess) {
        // 配置车辆协议
        return _configVechileProtocol(method);
      });
    } else {
      // 配置车辆协议
      return _configVechileProtocol(method);
    }
  }

  // 配置车辆协议
  Future<void> _configVechileProtocol(MessageSendMethod method) {
    if (method != protocol?.messageSendMethod) {
      debugPrint("⚠️⚠️⚠️ 车辆连接方式发生变化");
      // 当连接状态发生变化时，设置连接方式
      protocol?.setVehicleConnetionMethod(method);
    }
    if (protocol?.onMessageHttpSent == null) {
      // 设置HTTP数据处理器
      protocol?.setHttpConnetionDataProcessor((requestMessage) {
        var sn = GlobalService.to.currentVehicleModel.value.sn;
        return ApiHelper()
            .passThrough(
                sn, base64Encode(Uint8List.view(requestMessage.buffer)))
            .then((rsp) {
          debugPrint("✅ 透传发送数据成功: $rsp");
          return Future.value(base64Decode(rsp));
        });
      });
    }
    _resetLoopToGetVehicleRealTimeData();
    return Future.value();
  }

  // 重置周期性获取车辆实时数据
  _resetLoopToGetVehicleRealTimeData() {
    realtimeInfoMixinStopLoopToGetVehicleRealTimeData().then((_) {
      // 首页车辆控制器
      if (isRegisteredVehicleController) {
        debugPrint("⚠️ 重置首页车辆控制器的实时数据轮询");
        realtimeInfoMixinStartLoopToGetVehicleRealTimeData(
          pollingTypes:
              RealtimeDataPollingTimeHelper.vehicleHomePagePollingTypes,
        );
      }
      // 车辆实时数据详情控制器
      if (isRegisteredVehicleRealtimeDetailController) {
        debugPrint("⚠️ 重置车辆实时数据详情控制器的实时数据轮询");
        realtimeInfoMixinStartLoopToGetVehicleRealTimeData(
          pollingTypes:
              RealtimeDataPollingTimeHelper.vehicleDetailPagePollingTypes,
        );
      }
      // 车辆设置控制器
      if (isRegisteredVehicleSettingController) {
        debugPrint("⚠️ 重置车辆设置控制器的实时数据轮询");
        realtimeInfoMixinStartLoopToGetVehicleRealTimeData(
          pollingTypes:
              RealtimeDataPollingTimeHelper.vehicleSettingPagePollingTypes,
        );
      }
      // 车辆电池信息控制器
      if (isRegisteredBatteryInfoController) {
        debugPrint("⚠️ 重置车辆电池信息控制器的实时数据轮询");
        realtimeInfoMixinStartLoopToGetVehicleRealTimeData(
          pollingTypes:
              RealtimeDataPollingTimeHelper.vehicleBatteryInfoPagePollingTypes,
        );
      }
    });
  }
}
